<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/sure3.css" rel="stylesheet" type="text/css"/>
    <link href="../Styles/base1.css" rel="stylesheet" type="text/css"/>
</head>

<body>
<div class="markdown-body entry-content" itemprop="text">
    <h1><a href="#变量的解构赋值"  class="anchor" id="user-content-变量的解构赋值">
        
    </a>变量的解构赋值
    </h1>
    <h2><a href="#数组的解构赋值"  class="anchor" id="user-content-数组的解构赋值">
        
    </a>数组的解构赋值
    </h2>
    <h3><a href="#基本用法"  class="anchor" id="user-content-基本用法">
        
    </a>基本用法
    </h3>
    <p>ES6 允许按照一定模式，从数组和对象中提取值，对变量进行赋值，这被称为解构（Destructuring）。</p>
    <p>以前，为变量赋值，只能直接指定值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> a <span class="pl-k">=</span> <span
            class="pl-c1">1</span>;
<span class="pl-k">let</span> b <span class="pl-k">=</span> <span class="pl-c1">2</span>;
<span class="pl-k">let</span> c <span class="pl-k">=</span> <span class="pl-c1">3</span>;</pre>
    </div>
    <p>ES6 允许写成下面这样。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-k">let</span> [a, b, c] <span class="pl-k">=</span> [<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>];</pre>
    </div>
    <p>上面代码表示，可以从数组中提取值，按照对应位置，对变量赋值。</p>
    <p>本质上，这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [foo, [[bar], baz]] <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, [[<span class="pl-c1">2</span>], <span
            class="pl-c1">3</span>]];
foo <span class="pl-c"><span class="pl-c">//</span> 1</span>
bar <span class="pl-c"><span class="pl-c">//</span> 2</span>
baz <span class="pl-c"><span class="pl-c">//</span> 3</span>

<span class="pl-k">let</span> [ , , third] <span class="pl-k">=</span> [<span class="pl-s"><span class="pl-pds">"</span>foo<span
                class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>bar<span class="pl-pds">"</span></span>, <span
                class="pl-s"><span class="pl-pds">"</span>baz<span class="pl-pds">"</span></span>];
third <span class="pl-c"><span class="pl-c">//</span> "baz"</span>

<span class="pl-k">let</span> [x, , y] <span class="pl-k">=</span> [<span class="pl-c1">1</span>, <span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>];
x <span class="pl-c"><span class="pl-c">//</span> 1</span>
y <span class="pl-c"><span class="pl-c">//</span> 3</span>

<span class="pl-k">let</span> [head, <span class="pl-k">...</span>tail] <span class="pl-k">=</span> [<span
                class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>];
head <span class="pl-c"><span class="pl-c">//</span> 1</span>
tail <span class="pl-c"><span class="pl-c">//</span> [2, 3, 4]</span>

<span class="pl-k">let</span> [x, y, <span class="pl-k">...</span>z] <span class="pl-k">=</span> [<span
                class="pl-s"><span class="pl-pds">'</span>a<span class="pl-pds">'</span></span>];
x <span class="pl-c"><span class="pl-c">//</span> "a"</span>
y <span class="pl-c"><span class="pl-c">//</span> undefined</span>
z <span class="pl-c"><span class="pl-c">//</span> []</span></pre>
    </div>
    <p>如果解构不成功，变量的值就等于<code>undefined</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [foo] <span class="pl-k">=</span> [];
<span class="pl-k">let</span> [bar, foo] <span class="pl-k">=</span> [<span class="pl-c1">1</span>];</pre>
    </div>
    <p>以上两种情况都属于解构不成功，<code>foo</code>的值都会等于<code>undefined</code>。</p>
    <p>另一种情况是不完全解构，即等号左边的模式，只匹配一部分的等号右边的数组。这种情况下，解构依然可以成功。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [x, y] <span
            class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
            class="pl-c1">3</span>];
x <span class="pl-c"><span class="pl-c">//</span> 1</span>
y <span class="pl-c"><span class="pl-c">//</span> 2</span>

<span class="pl-k">let</span> [a, [b], d] <span class="pl-k">=</span> [<span class="pl-c1">1</span>, [<span
                class="pl-c1">2</span>, <span class="pl-c1">3</span>], <span class="pl-c1">4</span>];
a <span class="pl-c"><span class="pl-c">//</span> 1</span>
b <span class="pl-c"><span class="pl-c">//</span> 2</span>
d <span class="pl-c"><span class="pl-c">//</span> 4</span></pre>
    </div>
    <p>上面两个例子，都属于不完全解构，但是可以成功。</p>
    <p>如果等号的右边不是数组（或者严格地说，不是可遍历的结构，参见《Iterator》一章），那么将会报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 报错</span>
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> <span class="pl-c1">1</span>;
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> <span class="pl-c1">false</span>;
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> <span class="pl-c1">NaN</span>;
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> <span class="pl-c1">undefined</span>;
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> <span class="pl-c1">null</span>;
<span class="pl-k">let</span> [foo] <span class="pl-k">=</span> {};</pre>
    </div>
    <p>上面的语句都会报错，因为等号右边的值，要么转为对象以后不具备 Iterator 接口（前五个表达式），要么本身就不具备 Iterator 接口（最后一个表达式）。</p>
    <p>对于 Set 结构，也可以使用数组的解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [x, y, z] <span class="pl-k">=</span> <span
            class="pl-k">new</span> <span class="pl-en">Set</span>([<span class="pl-s"><span
            class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span class="pl-s"><span
            class="pl-pds">'</span>b<span class="pl-pds">'</span></span>, <span class="pl-s"><span
            class="pl-pds">'</span>c<span class="pl-pds">'</span></span>]);
x <span class="pl-c"><span class="pl-c">//</span> "a"</span></pre>
    </div>
    <p>事实上，只要某种数据结构具有 Iterator 接口，都可以采用数组形式的解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span><span class="pl-k">*</span> <span
            class="pl-en">fibs</span>() {
  <span class="pl-k">let</span> a <span class="pl-k">=</span> <span class="pl-c1">0</span>;
  <span class="pl-k">let</span> b <span class="pl-k">=</span> <span class="pl-c1">1</span>;
  <span class="pl-k">while</span> (<span class="pl-c1">true</span>) {
    <span class="pl-k">yield</span> a;
    [a, b] <span class="pl-k">=</span> [b, a <span class="pl-k">+</span> b];
  }
}

<span class="pl-k">let</span> [first, second, third, fourth, fifth, sixth] <span class="pl-k">=</span> <span
                class="pl-en">fibs</span>();
sixth <span class="pl-c"><span class="pl-c">//</span> 5</span></pre>
    </div>
    <p>上面代码中，<code>fibs</code>是一个 Generator 函数（参见《Generator 函数》一章），原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。</p>
    <h3><a href="#默认值"  class="anchor" id="user-content-默认值">
        
    </a>默认值
    </h3>
    <p>解构赋值允许指定默认值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [foo <span class="pl-k">=</span> <span
            class="pl-c1">true</span>] <span class="pl-k">=</span> [];
foo <span class="pl-c"><span class="pl-c">//</span> true</span>

<span class="pl-k">let</span> [x, y <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>b<span
                class="pl-pds">'</span></span>] <span class="pl-k">=</span> [<span class="pl-s"><span
                class="pl-pds">'</span>a<span class="pl-pds">'</span></span>]; <span class="pl-c"><span
                class="pl-c">//</span> x='a', y='b'</span>
<span class="pl-k">let</span> [x, y <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>b<span
                class="pl-pds">'</span></span>] <span class="pl-k">=</span> [<span class="pl-s"><span
                class="pl-pds">'</span>a<span class="pl-pds">'</span></span>, <span
                class="pl-c1">undefined</span>]; <span class="pl-c"><span
                class="pl-c">//</span> x='a', y='b'</span></pre>
    </div>
    <p>注意，ES6 内部使用严格相等运算符（<code>===</code>），判断一个位置是否有值。所以，如果一个数组成员不严格等于<code>undefined</code>，默认值是不会生效的。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [x <span class="pl-k">=</span> <span
            class="pl-c1">1</span>] <span class="pl-k">=</span> [<span class="pl-c1">undefined</span>];
x <span class="pl-c"><span class="pl-c">//</span> 1</span>

<span class="pl-k">let</span> [x <span class="pl-k">=</span> <span class="pl-c1">1</span>] <span class="pl-k">=</span> [<span
                class="pl-c1">null</span>];
x <span class="pl-c"><span class="pl-c">//</span> null</span></pre>
    </div>
    <p>上面代码中，如果一个数组成员是<code>null</code>，默认值就不会生效，因为<code>null</code>不严格等于<code>undefined</code>。</p>
    <p>如果默认值是一个表达式，那么这个表达式是惰性求值的，即只有在用到的时候，才会求值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">f</span>() {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span
                class="pl-pds">'</span>aaa<span class="pl-pds">'</span></span>);
}

<span class="pl-k">let</span> [x <span class="pl-k">=</span> <span class="pl-en">f</span>()] <span class="pl-k">=</span> [<span
                class="pl-c1">1</span>];</pre>
    </div>
    <p>上面代码中，因为<code>x</code>能取到值，所以函数<code>f</code>根本不会执行。上面的代码其实等价于下面的代码。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> x;
<span class="pl-k">if</span> ([<span class="pl-c1">1</span>][<span class="pl-c1">0</span>] <span class="pl-k">===</span> <span
                class="pl-c1">undefined</span>) {
  x <span class="pl-k">=</span> <span class="pl-en">f</span>();
} <span class="pl-k">else</span> {
  x <span class="pl-k">=</span> [<span class="pl-c1">1</span>][<span class="pl-c1">0</span>];
}</pre>
    </div>
    <p>默认值可以引用解构赋值的其他变量，但该变量必须已经声明。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> [x <span class="pl-k">=</span> <span
            class="pl-c1">1</span>, y <span class="pl-k">=</span> x] <span class="pl-k">=</span> [];     <span
            class="pl-c"><span class="pl-c">//</span> x=1; y=1</span>
<span class="pl-k">let</span> [x <span class="pl-k">=</span> <span class="pl-c1">1</span>, y <span class="pl-k">=</span> x] <span
                class="pl-k">=</span> [<span class="pl-c1">2</span>];    <span class="pl-c"><span class="pl-c">//</span> x=2; y=2</span>
<span class="pl-k">let</span> [x <span class="pl-k">=</span> <span class="pl-c1">1</span>, y <span class="pl-k">=</span> x] <span
                class="pl-k">=</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>]; <span
                class="pl-c"><span class="pl-c">//</span> x=1; y=2</span>
<span class="pl-k">let</span> [x <span class="pl-k">=</span> y, y <span class="pl-k">=</span> <span
                class="pl-c1">1</span>] <span class="pl-k">=</span> [];     <span class="pl-c"><span
                class="pl-c">//</span> ReferenceError</span></pre>
    </div>
    <p>上面最后一个表达式之所以会报错，是因为<code>x</code>用到默认值<code>y</code>时，<code>y</code>还没有声明。</p>
    <h2><a href="#对象的解构赋值"  class="anchor" id="user-content-对象的解构赋值">
        
    </a>对象的解构赋值
    </h2>
    <p>解构不仅可以用于数组，还可以用于对象。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> { foo, bar } <span
            class="pl-k">=</span> { foo<span class="pl-k">:</span> <span class="pl-s"><span
            class="pl-pds">"</span>aaa<span class="pl-pds">"</span></span>, bar<span class="pl-k">:</span> <span
            class="pl-s"><span class="pl-pds">"</span>bbb<span class="pl-pds">"</span></span> };
foo <span class="pl-c"><span class="pl-c">//</span> "aaa"</span>
bar <span class="pl-c"><span class="pl-c">//</span> "bbb"</span></pre>
    </div>
    <p>对象的解构与数组有一个重要的不同。数组的元素是按次序排列的，变量的取值由它的位置决定；而对象的属性没有次序，变量必须与属性同名，才能取到正确的值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> { bar, foo } <span
            class="pl-k">=</span> { foo<span class="pl-k">:</span> <span class="pl-s"><span
            class="pl-pds">"</span>aaa<span class="pl-pds">"</span></span>, bar<span class="pl-k">:</span> <span
            class="pl-s"><span class="pl-pds">"</span>bbb<span class="pl-pds">"</span></span> };
foo <span class="pl-c"><span class="pl-c">//</span> "aaa"</span>
bar <span class="pl-c"><span class="pl-c">//</span> "bbb"</span>

<span class="pl-k">let</span> { baz } <span class="pl-k">=</span> { foo<span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">"</span>aaa<span class="pl-pds">"</span></span>, bar<span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>bbb<span
                class="pl-pds">"</span></span> };
baz <span class="pl-c"><span class="pl-c">//</span> undefined</span></pre>
    </div>
    <p>上面代码的第一个例子，等号左边的两个变量的次序，与等号右边两个同名属性的次序不一致，但是对取值完全没有影响。第二个例子的变量没有对应的同名属性，导致取不到值，最后等于<code>undefined</code>。</p>
    <p>如果变量名与属性名不一致，必须写成下面这样。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> { foo<span class="pl-k">:</span> baz } <span
            class="pl-k">=</span> { foo<span class="pl-k">:</span> <span class="pl-s"><span
            class="pl-pds">'</span>aaa<span class="pl-pds">'</span></span>, bar<span class="pl-k">:</span> <span
            class="pl-s"><span class="pl-pds">'</span>bbb<span class="pl-pds">'</span></span> };
baz <span class="pl-c"><span class="pl-c">//</span> "aaa"</span>

<span class="pl-k">let</span> obj <span class="pl-k">=</span> { first<span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>, last<span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>world<span class="pl-pds">'</span></span> };
<span class="pl-k">let</span> { first<span class="pl-k">:</span> f, last<span class="pl-k">:</span> l } <span
                class="pl-k">=</span> obj;
f <span class="pl-c"><span class="pl-c">//</span> 'hello'</span>
l <span class="pl-c"><span class="pl-c">//</span> 'world'</span></pre>
    </div>
    <p>这实际上说明，对象的解构赋值是下面形式的简写（参见《对象的扩展》一章）。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-k">let</span> { foo<span class="pl-k">:</span> foo, bar<span
                class="pl-k">:</span> bar } <span class="pl-k">=</span> { foo<span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">"</span>aaa<span class="pl-pds">"</span></span>, bar<span
                class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>bbb<span
                class="pl-pds">"</span></span> };</pre>
    </div>
    <p>也就是说，对象的解构赋值的内部机制，是先找到同名属性，然后再赋给对应的变量。真正被赋值的是后者，而不是前者。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> { foo<span class="pl-k">:</span> baz } <span
            class="pl-k">=</span> { foo<span class="pl-k">:</span> <span class="pl-s"><span
            class="pl-pds">"</span>aaa<span class="pl-pds">"</span></span>, bar<span class="pl-k">:</span> <span
            class="pl-s"><span class="pl-pds">"</span>bbb<span class="pl-pds">"</span></span> };
baz <span class="pl-c"><span class="pl-c">//</span> "aaa"</span>
foo <span class="pl-c"><span class="pl-c">//</span> error: foo is not defined</span></pre>
    </div>
    <p>上面代码中，<code>foo</code>是匹配的模式，<code>baz</code>才是变量。真正被赋值的是变量<code>baz</code>，而不是模式<code>foo</code>。</p>
    <p>与数组一样，解构也可以用于嵌套结构的对象。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> obj <span class="pl-k">=</span> {
  p<span class="pl-k">:</span> [
    <span class="pl-s"><span class="pl-pds">'</span>Hello<span class="pl-pds">'</span></span>,
    { y<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>World<span
                class="pl-pds">'</span></span> }
  ]
};

<span class="pl-k">let</span> { p<span class="pl-k">:</span> [x, { y }] } <span class="pl-k">=</span> obj;
x <span class="pl-c"><span class="pl-c">//</span> "Hello"</span>
y <span class="pl-c"><span class="pl-c">//</span> "World"</span></pre>
    </div>
    <p>注意，这时<code>p</code>是模式，不是变量，因此不会被赋值。如果<code>p</code>也要作为变量赋值，可以写成下面这样。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> obj <span class="pl-k">=</span> {
  p<span class="pl-k">:</span> [
    <span class="pl-s"><span class="pl-pds">'</span>Hello<span class="pl-pds">'</span></span>,
    { y<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>World<span
                class="pl-pds">'</span></span> }
  ]
};

<span class="pl-k">let</span> { p, p<span class="pl-k">:</span> [x, { y }] } <span class="pl-k">=</span> obj;
x <span class="pl-c"><span class="pl-c">//</span> "Hello"</span>
y <span class="pl-c"><span class="pl-c">//</span> "World"</span>
p <span class="pl-c"><span class="pl-c">//</span> ["Hello", {y: "World"}]</span></pre>
    </div>
    <p>下面是另一个例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span
            class="pl-c1">node</span> <span class="pl-k">=</span> {
  loc<span class="pl-k">:</span> {
    start<span class="pl-k">:</span> {
      line<span class="pl-k">:</span> <span class="pl-c1">1</span>,
      column<span class="pl-k">:</span> <span class="pl-c1">5</span>
    }
  }
};

<span class="pl-k">let</span> { loc, loc<span class="pl-k">:</span> { start }, loc<span
                class="pl-k">:</span> { start<span class="pl-k">:</span> { line }} } <span class="pl-k">=</span> node;
line <span class="pl-c"><span class="pl-c">//</span> 1</span>
loc  <span class="pl-c"><span class="pl-c">//</span> Object {start: Object}</span>
start <span class="pl-c"><span class="pl-c">//</span> Object {line: 1, column: 5}</span></pre>
    </div>
    <p>上面代码有三次解构赋值，分别是对<code>loc</code>、<code>start</code>、<code>line</code>三个属性的解构赋值。注意，最后一次对<code>line</code>属性的解构赋值之中，只有<code>line</code>是变量，<code>loc</code>和<code>start</code>都是模式，不是变量。
    </p>
    <p>下面是嵌套赋值的例子。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> obj <span class="pl-k">=</span> {};
<span class="pl-k">let</span> arr <span class="pl-k">=</span> [];

({ foo<span class="pl-k">:</span> <span class="pl-smi">obj</span>.<span class="pl-smi">prop</span>, bar<span
                class="pl-k">:</span> arr[<span class="pl-c1">0</span>] } <span class="pl-k">=</span> { foo<span
                class="pl-k">:</span> <span class="pl-c1">123</span>, bar<span class="pl-k">:</span> <span
                class="pl-c1">true</span> });

obj <span class="pl-c"><span class="pl-c">//</span> {prop:123}</span>
arr <span class="pl-c"><span class="pl-c">//</span> [true]</span></pre>
    </div>
    <p>对象的解构也可以指定默认值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> {x <span class="pl-k">=</span> <span
            class="pl-c1">3</span>} <span class="pl-k">=</span> {};
x <span class="pl-c"><span class="pl-c">//</span> 3</span>

<span class="pl-k">var</span> {x, y <span class="pl-k">=</span> <span class="pl-c1">5</span>} <span
                class="pl-k">=</span> {x<span class="pl-k">:</span> <span class="pl-c1">1</span>};
x <span class="pl-c"><span class="pl-c">//</span> 1</span>
y <span class="pl-c"><span class="pl-c">//</span> 5</span>

<span class="pl-k">var</span> {x<span class="pl-k">:</span> y <span class="pl-k">=</span> <span class="pl-c1">3</span>} <span
                class="pl-k">=</span> {};
y <span class="pl-c"><span class="pl-c">//</span> 3</span>

<span class="pl-k">var</span> {x<span class="pl-k">:</span> y <span class="pl-k">=</span> <span class="pl-c1">3</span>} <span
                class="pl-k">=</span> {x<span class="pl-k">:</span> <span class="pl-c1">5</span>};
y <span class="pl-c"><span class="pl-c">//</span> 5</span>

<span class="pl-k">var</span> { message<span class="pl-k">:</span> msg <span class="pl-k">=</span> <span
                class="pl-s"><span class="pl-pds">'</span>Something went wrong<span
                class="pl-pds">'</span></span> } <span class="pl-k">=</span> {};
msg <span class="pl-c"><span class="pl-c">//</span> "Something went wrong"</span></pre>
    </div>
    <p>默认值生效的条件是，对象的属性值严格等于<code>undefined</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> {x <span class="pl-k">=</span> <span
            class="pl-c1">3</span>} <span class="pl-k">=</span> {x<span class="pl-k">:</span> <span class="pl-c1">undefined</span>};
x <span class="pl-c"><span class="pl-c">//</span> 3</span>

<span class="pl-k">var</span> {x <span class="pl-k">=</span> <span class="pl-c1">3</span>} <span class="pl-k">=</span> {x<span
                class="pl-k">:</span> <span class="pl-c1">null</span>};
x <span class="pl-c"><span class="pl-c">//</span> null</span></pre>
    </div>
    <p>上面代码中，如果<code>x</code>属性等于<code>null</code>，就不严格相等于<code>undefined</code>，导致默认值不会生效。</p>
    <p>如果解构失败，变量的值等于<code>undefined</code>。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> {foo} <span class="pl-k">=</span> {bar<span
            class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>baz<span
            class="pl-pds">'</span></span>};
foo <span class="pl-c"><span class="pl-c">//</span> undefined</span></pre>
    </div>
    <p>如果解构模式是嵌套的对象，而且子对象所在的父属性不存在，那么将会报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 报错</span>
<span class="pl-k">let</span> {foo<span class="pl-k">:</span> {bar}} <span class="pl-k">=</span> {baz<span class="pl-k">:</span> <span
                class="pl-s"><span class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>};</pre>
    </div>
    <p>上面代码中，等号左边对象的<code>foo</code>属性，对应一个子对象。该子对象的<code>bar</code>属性，解构时会报错。原因很简单，因为<code>foo</code>这时等于<code>undefined</code>，再取子属性就会报错，请看下面的代码。
    </p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> _tmp <span
            class="pl-k">=</span> {baz<span class="pl-k">:</span> <span class="pl-s"><span
            class="pl-pds">'</span>baz<span class="pl-pds">'</span></span>};
<span class="pl-smi">_tmp</span>.<span class="pl-smi">foo</span>.<span class="pl-smi">bar</span> <span
                class="pl-c"><span class="pl-c">//</span> 报错</span></pre>
    </div>
    <p>如果要将一个已经声明的变量用于解构赋值，必须非常小心。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 错误的写法</span>
<span class="pl-k">let</span> x;
{x} <span class="pl-k">=</span> {x<span class="pl-k">:</span> <span class="pl-c1">1</span>};
<span class="pl-c"><span class="pl-c">//</span> SyntaxError: syntax error</span></pre>
    </div>
    <p>上面代码的写法会报错，因为 JavaScript 引擎会将<code>{x}</code>理解成一个代码块，从而发生语法错误。只有不将大括号写在行首，避免 JavaScript 将其解释为代码块，才能解决这个问题。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 正确的写法</span>
<span class="pl-k">let</span> x;
({x} <span class="pl-k">=</span> {x<span class="pl-k">:</span> <span class="pl-c1">1</span>});</pre>
    </div>
    <p>上面代码将整个解构赋值语句，放在一个圆括号里面，就可以正确执行。关于圆括号与解构赋值的关系，参见下文。</p>
    <p>解构赋值允许等号左边的模式之中，不放置任何变量名。因此，可以写出非常古怪的赋值表达式。</p>
    <div class="highlight highlight-source-js"><pre>({} <span class="pl-k">=</span> [<span
            class="pl-c1">true</span>, <span class="pl-c1">false</span>]);
({} <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>abc<span class="pl-pds">'</span></span>);
({} <span class="pl-k">=</span> []);</pre>
    </div>
    <p>上面的表达式虽然毫无意义，但是语法是合法的，可以执行。</p>
    <p>对象的解构赋值，可以很方便地将现有对象的方法，赋值到某个变量。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-k">let</span> { log, sin, cos } <span class="pl-k">=</span> <span class="pl-c1">Math</span>;</pre>
    </div>
    <p>上面代码将<code>Math</code>对象的对数、正弦、余弦三个方法，赋值到对应的变量上，使用起来就会方便很多。</p>
    <p>由于数组本质是特殊的对象，因此可以对数组进行对象属性的解构。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> arr <span class="pl-k">=</span> [<span
            class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>];
<span class="pl-k">let</span> {<span class="pl-c1">0</span> <span class="pl-k">:</span> first, [<span
                class="pl-smi">arr</span>.<span class="pl-c1">length</span> <span class="pl-k">-</span> <span
                class="pl-c1">1</span>] <span class="pl-k">:</span> last} <span class="pl-k">=</span> arr;
first <span class="pl-c"><span class="pl-c">//</span> 1</span>
last <span class="pl-c"><span class="pl-c">//</span> 3</span></pre>
    </div>
    <p>上面代码对数组进行对象解构。数组<code>arr</code>的<code>0</code>键对应的值是<code>1</code>，<code>[arr.length - 1]</code>就是<code>2</code>键，对应的值是<code>3</code>。方括号这种写法，属于“属性名表达式”，参见《对象的扩展》一章。
    </p>
    <h2><a href="#字符串的解构赋值"  class="anchor" id="user-content-字符串的解构赋值">
        
    </a>字符串的解构赋值
    </h2>
    <p>字符串也可以解构赋值。这是因为此时，字符串被转换成了一个类似数组的对象。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> [<span class="pl-c1">a</span>, <span
            class="pl-c1">b</span>, <span class="pl-c1">c</span>, <span class="pl-c1">d</span>, <span
            class="pl-c1">e</span>] <span class="pl-k">=</span> <span class="pl-s"><span
            class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>;
a <span class="pl-c"><span class="pl-c">//</span> "h"</span>
b <span class="pl-c"><span class="pl-c">//</span> "e"</span>
c <span class="pl-c"><span class="pl-c">//</span> "l"</span>
d <span class="pl-c"><span class="pl-c">//</span> "l"</span>
e <span class="pl-c"><span class="pl-c">//</span> "o"</span></pre>
    </div>
    <p>类似数组的对象都有一个<code>length</code>属性，因此还可以对这个属性解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> {length <span class="pl-k">:</span> len} <span
            class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>hello<span
            class="pl-pds">'</span></span>;
len <span class="pl-c"><span class="pl-c">//</span> 5</span></pre>
    </div>
    <h2><a href="#数值和布尔值的解构赋值"  class="anchor" id="user-content-数值和布尔值的解构赋值">
        
    </a>数值和布尔值的解构赋值
    </h2>
    <p>解构赋值时，如果等号右边是数值和布尔值，则会先转为对象。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> {toString<span class="pl-k">:</span> s} <span
            class="pl-k">=</span> <span class="pl-c1">123</span>;
s <span class="pl-k">===</span> <span class="pl-c1">Number</span>.<span class="pl-c1">prototype</span>.<span
                class="pl-smi">toString</span> <span class="pl-c"><span class="pl-c">//</span> true</span>

<span class="pl-k">let</span> {toString<span class="pl-k">:</span> s} <span class="pl-k">=</span> <span class="pl-c1">true</span>;
s <span class="pl-k">===</span> <span class="pl-c1">Boolean</span>.<span class="pl-c1">prototype</span>.<span
                class="pl-smi">toString</span> <span class="pl-c"><span class="pl-c">//</span> true</span></pre>
    </div>
    <p>上面代码中，数值和布尔值的包装对象都有<code>toString</code>属性，因此变量<code>s</code>都能取到值。</p>
    <p>解构赋值的规则是，只要等号右边的值不是对象或数组，就先将其转为对象。由于<code>undefined</code>和<code>null</code>无法转为对象，所以对它们进行解构赋值，都会报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> { prop<span class="pl-k">:</span> x } <span
            class="pl-k">=</span> <span class="pl-c1">undefined</span>; <span class="pl-c"><span class="pl-c">//</span> TypeError</span>
<span class="pl-k">let</span> { prop<span class="pl-k">:</span> y } <span class="pl-k">=</span> <span
                class="pl-c1">null</span>; <span class="pl-c"><span class="pl-c">//</span> TypeError</span></pre>
    </div>
    <h2><a href="#函数参数的解构赋值"  class="anchor" id="user-content-函数参数的解构赋值">
        
    </a>函数参数的解构赋值
    </h2>
    <p>函数的参数也可以使用解构赋值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span
            class="pl-en">add</span>([<span class="pl-smi">x</span>, <span class="pl-smi">y</span>]){
  <span class="pl-k">return</span> x <span class="pl-k">+</span> y;
}

<span class="pl-en">add</span>([<span class="pl-c1">1</span>, <span class="pl-c1">2</span>]); <span class="pl-c"><span
                class="pl-c">//</span> 3</span></pre>
    </div>
    <p>
        上面代码中，函数<code>add</code>的参数表面上是一个数组，但在传入参数的那一刻，数组参数就被解构成变量<code>x</code>和<code>y</code>。对于函数内部的代码来说，它们能感受到的参数就是<code>x</code>和<code>y</code>。
    </p>
    <p>下面是另一个例子。</p>
    <div class="highlight highlight-source-js"><pre>[[<span class="pl-c1">1</span>, <span
            class="pl-c1">2</span>], [<span class="pl-c1">3</span>, <span class="pl-c1">4</span>]].<span class="pl-en">map</span>(([<span
            class="pl-smi">a</span>, <span class="pl-smi">b</span>]) <span class="pl-k">=&gt;</span> a <span
            class="pl-k">+</span> b);
<span class="pl-c"><span class="pl-c">//</span> [ 3, 7 ]</span></pre>
    </div>
    <p>函数参数的解构也可以使用默认值。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">move</span>({x <span
            class="pl-k">=</span> <span class="pl-c1">0</span>, y <span class="pl-k">=</span> <span
            class="pl-c1">0</span>} <span class="pl-k">=</span> {}) {
  <span class="pl-k">return</span> [x, y];
}

<span class="pl-en">move</span>({x<span class="pl-k">:</span> <span class="pl-c1">3</span>, y<span class="pl-k">:</span> <span
                class="pl-c1">8</span>}); <span class="pl-c"><span class="pl-c">//</span> [3, 8]</span>
<span class="pl-en">move</span>({x<span class="pl-k">:</span> <span class="pl-c1">3</span>}); <span class="pl-c"><span
                class="pl-c">//</span> [3, 0]</span>
<span class="pl-en">move</span>({}); <span class="pl-c"><span class="pl-c">//</span> [0, 0]</span>
<span class="pl-en">move</span>(); <span class="pl-c"><span class="pl-c">//</span> [0, 0]</span></pre>
    </div>
    <p>
        上面代码中，函数<code>move</code>的参数是一个对象，通过对这个对象进行解构，得到变量<code>x</code>和<code>y</code>的值。如果解构失败，<code>x</code>和<code>y</code>等于默认值。
    </p>
    <p>注意，下面的写法会得到不一样的结果。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">move</span>({x, y} <span
            class="pl-k">=</span> { x<span class="pl-k">:</span> <span class="pl-c1">0</span>, y<span
            class="pl-k">:</span> <span class="pl-c1">0</span> }) {
  <span class="pl-k">return</span> [x, y];
}

<span class="pl-en">move</span>({x<span class="pl-k">:</span> <span class="pl-c1">3</span>, y<span class="pl-k">:</span> <span
                class="pl-c1">8</span>}); <span class="pl-c"><span class="pl-c">//</span> [3, 8]</span>
<span class="pl-en">move</span>({x<span class="pl-k">:</span> <span class="pl-c1">3</span>}); <span class="pl-c"><span
                class="pl-c">//</span> [3, undefined]</span>
<span class="pl-en">move</span>({}); <span class="pl-c"><span class="pl-c">//</span> [undefined, undefined]</span>
<span class="pl-en">move</span>(); <span class="pl-c"><span class="pl-c">//</span> [0, 0]</span></pre>
    </div>
    <p>上面代码是为函数<code>move</code>的参数指定默认值，而不是为变量<code>x</code>和<code>y</code>指定默认值，所以会得到与前一种写法不同的结果。</p>
    <p><code>undefined</code>就会触发函数参数的默认值。</p>
    <div class="highlight highlight-source-js"><pre>[<span class="pl-c1">1</span>, <span class="pl-c1">undefined</span>, <span
            class="pl-c1">3</span>].<span class="pl-en">map</span>((<span class="pl-smi">x</span> <span
            class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>yes<span
            class="pl-pds">'</span></span>) <span class="pl-k">=&gt;</span> x);
<span class="pl-c"><span class="pl-c">//</span> [ 1, 'yes', 3 ]</span></pre>
    </div>
    <h2><a href="#圆括号问题"  class="anchor" id="user-content-圆括号问题">
        
    </a>圆括号问题
    </h2>
    <p>解构赋值虽然很方便，但是解析起来并不容易。对于编译器来说，一个式子到底是模式，还是表达式，没有办法从一开始就知道，必须解析到（或解析不到）等号才能知道。</p>
    <p>由此带来的问题是，如果模式中出现圆括号怎么处理。ES6 的规则是，只要有可能导致解构的歧义，就不得使用圆括号。</p>
    <p>但是，这条规则实际上不那么容易辨别，处理起来相当麻烦。因此，建议只要有可能，就不要在模式中放置圆括号。</p>
    <h3><a href="#不能使用圆括号的情况"  class="anchor" id="user-content-不能使用圆括号的情况">
        
    </a>不能使用圆括号的情况
    </h3>
    <p>以下三种解构赋值不得使用圆括号。</p>
    <p>（1）变量声明语句</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 全部报错</span>
<span class="pl-k">let</span> [(a)] <span class="pl-k">=</span> [<span class="pl-c1">1</span>];

<span class="pl-k">let</span> {x<span class="pl-k">:</span> (c)} <span class="pl-k">=</span> {};
<span class="pl-k">let</span> ({x<span class="pl-k">:</span> c}) <span class="pl-k">=</span> {};
<span class="pl-k">let</span> {(x<span class="pl-k">:</span> c)} <span class="pl-k">=</span> {};
<span class="pl-k">let</span> {(x)<span class="pl-k">:</span> c} <span class="pl-k">=</span> {};

<span class="pl-k">let</span> { o<span class="pl-k">:</span> ({ p<span class="pl-k">:</span> p }) } <span
                class="pl-k">=</span> { o<span class="pl-k">:</span> { p<span class="pl-k">:</span> <span class="pl-c1">2</span> } };</pre>
    </div>
    <p>上面 6 个语句都会报错，因为它们都是变量声明语句，模式不能使用圆括号。</p>
    <p>（2）函数参数</p>
    <p>函数参数也属于变量声明，因此不能带有圆括号。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 报错</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>([(z)]) { <span class="pl-k">return</span> z; }
<span class="pl-c"><span class="pl-c">//</span> 报错</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>([<span class="pl-smi">z</span>,(x)]) { <span
                class="pl-k">return</span> x; }</pre>
    </div>
    <p>（3）赋值语句的模式</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 全部报错</span>
({ p<span class="pl-k">:</span> a }) <span class="pl-k">=</span> { p<span class="pl-k">:</span> <span
                class="pl-c1">42</span> };
([a]) <span class="pl-k">=</span> [<span class="pl-c1">5</span>];</pre>
    </div>
    <p>上面代码将整个模式放在圆括号之中，导致报错。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 报错</span>
[({ p<span class="pl-k">:</span> a }), { x<span class="pl-k">:</span> c }] <span class="pl-k">=</span> [{}, {}];</pre>
    </div>
    <p>上面代码将一部分模式放在圆括号之中，导致报错。</p>
    <h3><a href="#可以使用圆括号的情况"  class="anchor" id="user-content-可以使用圆括号的情况">
        
    </a>可以使用圆括号的情况
    </h3>
    <p>可以使用圆括号的情况只有一种：赋值语句的非模式部分，可以使用圆括号。</p>
    <div class="highlight highlight-source-js"><pre>[(b)] <span class="pl-k">=</span> [<span
            class="pl-c1">3</span>]; <span class="pl-c"><span class="pl-c">//</span> 正确</span>
({ p<span class="pl-k">:</span> (d) } <span class="pl-k">=</span> {}); <span class="pl-c"><span class="pl-c">//</span> 正确</span>
[(<span class="pl-smi">parseInt</span>.<span class="pl-smi">prop</span>)] <span class="pl-k">=</span> [<span
                class="pl-c1">3</span>]; <span class="pl-c"><span class="pl-c">//</span> 正确</span></pre>
    </div>
    <p>
        上面三行语句都可以正确执行，因为首先它们都是赋值语句，而不是声明语句；其次它们的圆括号都不属于模式的一部分。第一行语句中，模式是取数组的第一个成员，跟圆括号无关；第二行语句中，模式是<code>p</code>，而不是<code>d</code>；第三行语句与第一行语句的性质一致。
    </p>
    <h2><a href="#用途"  class="anchor" id="user-content-用途">
        
    </a>用途
    </h2>
    <p>变量的解构赋值用途很多。</p>
    <p><strong>（1）交换变量的值</strong></p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> x <span class="pl-k">=</span> <span
            class="pl-c1">1</span>;
<span class="pl-k">let</span> y <span class="pl-k">=</span> <span class="pl-c1">2</span>;

[x, y] <span class="pl-k">=</span> [y, x];</pre>
    </div>
    <p>上面代码交换变量<code>x</code>和<code>y</code>的值，这样的写法不仅简洁，而且易读，语义非常清晰。</p>
    <p><strong>（2）从函数返回多个值</strong></p>
    <p>函数只能返回一个值，如果要返回多个值，只能将它们放在数组或对象里返回。有了解构赋值，取出这些值就非常方便。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 返回一个数组</span>

<span class="pl-k">function</span> <span class="pl-en">example</span>() {
  <span class="pl-k">return</span> [<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span
                class="pl-c1">3</span>];
}
<span class="pl-k">let</span> [a, b, c] <span class="pl-k">=</span> <span class="pl-en">example</span>();

<span class="pl-c"><span class="pl-c">//</span> 返回一个对象</span>

<span class="pl-k">function</span> <span class="pl-en">example</span>() {
  <span class="pl-k">return</span> {
    foo<span class="pl-k">:</span> <span class="pl-c1">1</span>,
    bar<span class="pl-k">:</span> <span class="pl-c1">2</span>
  };
}
<span class="pl-k">let</span> { foo, bar } <span class="pl-k">=</span> <span class="pl-en">example</span>();</pre>
    </div>
    <p><strong>（3）函数参数的定义</strong></p>
    <p>解构赋值可以方便地将一组参数与变量名对应起来。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 参数是一组有次序的值</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>([<span class="pl-smi">x</span>, <span
                class="pl-smi">y</span>, <span class="pl-smi">z</span>]) { <span class="pl-k">...</span> }
<span class="pl-en">f</span>([<span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>]);

<span class="pl-c"><span class="pl-c">//</span> 参数是一组无次序的值</span>
<span class="pl-k">function</span> <span class="pl-en">f</span>({x, y, z}) { <span class="pl-k">...</span> }
<span class="pl-en">f</span>({z<span class="pl-k">:</span> <span class="pl-c1">3</span>, y<span
                class="pl-k">:</span> <span class="pl-c1">2</span>, x<span class="pl-k">:</span> <span
                class="pl-c1">1</span>});</pre>
    </div>
    <p><strong>（4）提取 JSON 数据</strong></p>
    <p>解构赋值对提取 JSON 对象中的数据，尤其有用。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">let</span> jsonData <span class="pl-k">=</span> {
  id<span class="pl-k">:</span> <span class="pl-c1">42</span>,
  status<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>OK<span
                class="pl-pds">"</span></span>,
  data<span class="pl-k">:</span> [<span class="pl-c1">867</span>, <span class="pl-c1">5309</span>]
};

<span class="pl-k">let</span> { id, status, data<span class="pl-k">:</span> number } <span class="pl-k">=</span> jsonData;

<span class="pl-en">console</span>.<span class="pl-c1">log</span>(id, status, number);
<span class="pl-c"><span class="pl-c">//</span> 42, "OK", [867, 5309]</span></pre>
    </div>
    <p>上面代码可以快速提取 JSON 数据的值。</p>
    <p><strong>（5）函数参数的默认值</strong></p>
    <div class="highlight highlight-source-js"><pre><span class="pl-smi">jQuery</span>.<span
            class="pl-en">ajax</span> <span class="pl-k">=</span> <span class="pl-k">function</span> (<span
            class="pl-smi">url</span>, {
  <span class="pl-k">async</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>,
  <span class="pl-en">beforeSend</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () {},
  cache <span class="pl-k">=</span> <span class="pl-c1">true</span>,
  <span class="pl-en">complete</span> <span class="pl-k">=</span> <span class="pl-k">function</span> () {},
  crossDomain <span class="pl-k">=</span> <span class="pl-c1">false</span>,
  <span class="pl-c1">global</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>,
  <span class="pl-c"><span class="pl-c">//</span> ... more config</span>
}) {
  <span class="pl-c"><span class="pl-c">//</span> ... do stuff</span>
};</pre>
    </div>
    <p>指定参数的默认值，就避免了在函数体内部再写<code>var foo = config.foo || 'default foo';</code>这样的语句。</p>
    <p><strong>（6）遍历 Map 结构</strong></p>
    <p>任何部署了 Iterator 接口的对象，都可以用<code>for...of</code>循环遍历。Map 结构原生支持 Iterator 接口，配合变量的解构赋值，获取键名和键值就非常方便。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-k">const</span> <span class="pl-c1">map</span> <span
            class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Map</span>();
<span class="pl-smi">map</span>.<span class="pl-c1">set</span>(<span class="pl-s"><span
                class="pl-pds">'</span>first<span class="pl-pds">'</span></span>, <span class="pl-s"><span
                class="pl-pds">'</span>hello<span class="pl-pds">'</span></span>);
<span class="pl-smi">map</span>.<span class="pl-c1">set</span>(<span class="pl-s"><span
                class="pl-pds">'</span>second<span class="pl-pds">'</span></span>, <span class="pl-s"><span
                class="pl-pds">'</span>world<span class="pl-pds">'</span></span>);

<span class="pl-k">for</span> (<span class="pl-k">let</span> [key, value] <span class="pl-k">of</span> map) {
  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(key <span class="pl-k">+</span> <span
                class="pl-s"><span class="pl-pds">"</span> is <span class="pl-pds">"</span></span> <span
                class="pl-k">+</span> value);
}
<span class="pl-c"><span class="pl-c">//</span> first is hello</span>
<span class="pl-c"><span class="pl-c">//</span> second is world</span></pre>
    </div>
    <p>如果只想获取键名，或者只想获取键值，可以写成下面这样。</p>
    <div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">//</span> 获取键名</span>
<span class="pl-k">for</span> (<span class="pl-k">let</span> [key] <span class="pl-k">of</span> map) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}

<span class="pl-c"><span class="pl-c">//</span> 获取键值</span>
<span class="pl-k">for</span> (<span class="pl-k">let</span> [,value] <span class="pl-k">of</span> map) {
  <span class="pl-c"><span class="pl-c">//</span> ...</span>
}</pre>
    </div>
    <p><strong>（7）输入模块的指定方法</strong></p>
    <p>加载模块时，往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。</p>
    <div class="highlight highlight-source-js">
        <pre><span class="pl-k">const</span> { <span class="pl-c1">SourceMapConsumer</span>, <span class="pl-c1">SourceNode</span> } <span
                class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span
                class="pl-pds">"</span>source-map<span class="pl-pds">"</span></span>);</pre>
    </div>
</div>

</body>
</html>
